import { memo, useEffect, useState } from 'react'
import { produce } from 'immer'

import { ctx } from './ctx'

const Demo = memo(function Demo() {
  const xxx = ctx.useSelector(v => v.xxx)
  const yyy = ctx.useSelector(v => v.yyy)
  const zzz = ctx.useSelector(v => v.zzz)
  const subscribe = ctx.useSelector(v => v.subscribe)
  const getValue = ctx.useSelector(v => v.getValue)
  const setState = ctx.useSelector(v => v.setState)

  const [changedCount, setChangedCount] = useState(0)

  // 变更状态常规用法
  const incrementFn = () => {
    setState({ xxx: xxx + 1 })
  }

  // 变更状态回调用法 + immer 用法
  const decrementFn = () => {
    setState(prev => {
      return produce(prev, draft => {
        draft.xxx = draft.xxx - 1
      })
    })
  }

  // 以同步方式进行值变更订阅，记得清理（useEffect、useLayoutEffect 则是异步进行）
  useEffect(() => {
    return subscribe((value, prevValue) => {
      if (value.xxx === prevValue.xxx) return
      setChangedCount(v => ++v)
      console.log('xxx:', value.xxx)
      console.log('prevXxx:', prevValue.xxx)
    })
  }, [getValue, subscribe])

  // 获取最新值（在异步中使用、为减少依赖项而使用）
  useEffect(() => {
    setTimeout(() => {
      console.log('getValue():', getValue().xxx)
    }, 5000)
  }, [getValue])

  return (
    <div>
      <a onClick={incrementFn}>点击xxx自增: {xxx}</a>
      <br />
      <a onClick={decrementFn}>点击xxx自减: {xxx}</a>
      <hr />
      <div>yyy: {`${yyy}`}</div>
      <hr />
      <a onClick={() => zzz()}>点击执行zzz(): {xxx}</a>
      <hr />
      <div>changedCount: {changedCount}</div>
    </div>
  )
})

const Layout = () => {
  const xxx = ctx.useSelector(v => v.xxx)

  return (
    <div style={{ userSelect: 'none' }}>
      <div>{xxx % 2 === 0 ? '展开' : '收起'}</div>
      <hr />
      <Demo />
    </div>
  )
}

/** 业务模块说明 */
export const Xxx = memo(function Xxx() {
  return (
    <ctx.Provider>
      <Layout />
    </ctx.Provider>
  )
})
